/*
 * Copyright (C) 2003, Velocityme Partnership
 * TaskBean.java
 *
 * Created on 28 April 2003, 08:13
 */

package com.velocityme.entity;

import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import java.util.*;

import com.velocityme.interfaces.*;
import com.velocityme.valueobjects.ContactableValue;
import com.velocityme.valueobjects.TaskValue;
import com.velocityme.valueobjects.PersonValue;

/**
 *
 * @author  Robert Crida Work
 * @ejb.bean
 *           type="CMP"
 *           cmp-version="2.x"
 *           name="Task"
 *           jndi-name="ejb/Task"
 *           view-type="local"
 * @ejb.transaction type="Required"
 *
 * @ejb.value-object match="*"
 *
 * @ejb.persistence table-name="task"
 *
 * @ejb.util generate="physical"
 *
 * @ejb.finder signature="java.util.Collection findAllMyResponsibleTasks(com.velocityme.interfaces.ContactableLocal p_contactable)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Task t, IN (t.responsibleContactablesLocal) p WHERE p = ?1" 
 *
 * @ejb.finder signature="java.util.Collection findMyResponsibleTasks(com.velocityme.interfaces.SearchLocal p_search, com.velocityme.interfaces.ContactableLocal p_contactable)"
 *                query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) k, Task t, IN (t.responsibleContactablesLocal) p WHERE s = ?1 AND t.nodeLocal = k AND p = ?2"
 *
 * @ejb.finder signature="java.util.Collection findAllMyInterestedTasks(com.velocityme.interfaces.ContactableLocal p_contactable)"
 *              query="SELECT DISTINCT OBJECT(t) FROM Task t, IN (t.interestedContactablesLocal) p WHERE p = ?1" 
 *
 * @ejb.finder signature="java.util.Collection findMyInterestedTasks(com.velocityme.interfaces.SearchLocal p_search, com.velocityme.interfaces.ContactableLocal p_contactable)"
 *                query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) k, Task t, IN (t.interestedContactablesLocal) p WHERE s = ?1 AND t.nodeLocal = k AND p = ?2"
 *
 * @ejb.finder signature="java.util.Collection findActiveTasks(com.velocityme.interfaces.SearchLocal p_search)"
 *                query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) k, Task t WHERE s = ?1 AND t.nodeLocal = k AND t.stateLocal.nodeLocal.name <> 'Start State'" 
 *
 * @ejb.finder signature="java.util.Collection findTasksByState(com.velocityme.interfaces.SearchLocal p_search, com.velocityme.interfaces.StateLocal p_stateLocal)"
 *                query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) k, Task t WHERE s = ?1 AND t.nodeLocal = k AND t.stateLocal = ?2" 
 *
 * @ejb.finder signature="java.util.Collection findTasks(com.velocityme.interfaces.SearchLocal p_search)"
 *                query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) k, Task t WHERE s = ?1 AND t.nodeLocal = k" 
 *
 * @jboss.persistence create-table="true"
 *                    remove-table="false"
 */
public abstract class TaskBean implements EntityBean {
    
    /**
    * Context set by container
    */
    private javax.ejb.EntityContext m_entityContext;

    public void setEntityContext(javax.ejb.EntityContext entityContext) {
        m_entityContext = entityContext;
    }

    public void unsetEntityContext() {
        m_entityContext = null;
    }
      
    /** @ejb.create-method */
    public com.velocityme.interfaces.TaskPK ejbCreate(com.velocityme.interfaces.NodeLocal p_nodeLocal,
                                                      com.velocityme.valueobjects.TaskValue p_value) throws CreateException {
        setTaskId(p_nodeLocal.getNodeId());
        // EJB 2.0 spec says return null for CMP ejbCreate methods.
        return null;
    }

    public void ejbPostCreate(com.velocityme.interfaces.NodeLocal p_nodeLocal,
                              com.velocityme.valueobjects.TaskValue p_value) throws CreateException {
        // CMR relations must be set in ejbPostCreate
        setTaskValue(p_value);
        setNodeLocal(p_nodeLocal);
    }

    /**
     *  This gets a local object from a remote object.
     *  @ejb.interface-method view-type="remote"
     */
    public com.velocityme.interfaces.TaskLocal getLocal() {
        return (TaskLocal)m_entityContext.getEJBLocalObject();
    }
    
    /** @ejb.interface-method view-type="local" */
    public abstract com.velocityme.valueobjects.TaskValue getTaskValue();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTaskValue(com.velocityme.valueobjects.TaskValue p_value);
        
    //=======================================================================
    //
    //                   ATTRIBUTES
    //
    //=======================================================================
      
    /**
     * @ejb.persistence column-name="taskId"
     * @ejb.interface-method view-type="local"
     * @ejb.pk-field 
     */
    public abstract java.lang.Integer getTaskId();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTaskId(java.lang.Integer taskId);

    /**
     * @ejb.persistence column-name="type"
     * @ejb.interface-method view-type="both"
     */
    public abstract java.lang.String getType();
    /** @ejb.interface-method view-type="local" */
    public abstract void setType(java.lang.String description);
    
    /**
     * @ejb.persistence column-name="priority"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.lang.Integer getPriority();
    /** @ejb.interface-method view-type="local" */
    public abstract void setPriority(java.lang.Integer priority);

    /**
     * @ejb.persistence column-name="percentageComplete"
     * @ejb.interface-method view-type="both"
     */
    public abstract java.lang.Byte getPercentageComplete();
    /** @ejb.interface-method view-type="local" */
    public abstract void setPercentageComplete(java.lang.Byte percentageComplete);
    
    /**
     * @ejb.persistence column-name="expectedDuration_min"
     * @ejb.interface-method view-type="both"
     */
    public abstract java.lang.Integer getExpectedDuration_min();
    /** @ejb.interface-method view-type="local" */
    public abstract void setExpectedDuration_min(java.lang.Integer expectedDuration_min);
    
    /**
     * @ejb.persistence column-name="remainingDuration_min"
     * @ejb.interface-method view-type="both"
     */
    public abstract java.lang.Integer getRemainingDuration_min();
    /** @ejb.interface-method view-type="local" */
    public abstract void setRemainingDuration_min(java.lang.Integer remainingDuration_min);
    
    /**
     * @ejb.persistence column-name="startDate"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getStartDate();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStartDate(java.util.Date startDate);
    
    /**
     * @ejb.persistence column-name="stopDate"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getStopDate();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStopDate(java.util.Date stopDate);
    
    /**
     * @ejb.persistence column-name="cachedStartDate"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getCachedStartDate();
    /** @ejb.interface-method view-type="local" */
    public abstract void setCachedStartDate(java.util.Date cachedStartDate);
    
    /**
     * @ejb.persistence column-name="cachedStopDate"
     * @ejb.interface-method view-type="local"
     */
    public abstract java.util.Date getCachedStopDate();
    /** @ejb.interface-method view-type="local" */
    public abstract void setCachedStopDate(java.util.Date cachedStopDate);
    
    //=======================================================================
    //
    //                   RELATIONSHIPS
    //
    //=======================================================================
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-Node"
     *               role-name="Task-has-a-Node"
     * @jboss.relation fk-column="nodeIdFk"
     *                 related-pk-field="nodeId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.NodeValue"
     *                   aggregate-name="NodeValue"
     */
    public abstract com.velocityme.interfaces.NodeLocal getNodeLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setNodeLocal(com.velocityme.interfaces.NodeLocal nodeLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Project-Task"
     *               role-name="Task-may-have-a-Project"
     */
    public abstract com.velocityme.interfaces.ProjectLocal getProjectLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setProjectLocal(com.velocityme.interfaces.ProjectLocal projectLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Anchor-Task"
     *               role-name="Task-may-have-an-Anchor"
     */
    public abstract com.velocityme.interfaces.AnchorLocal getAnchorLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setAnchorLocal(com.velocityme.interfaces.AnchorLocal anchorLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Action-Task"
     *               role-name="Task-may-have-an-Action"
     */
    public abstract com.velocityme.interfaces.ActionLocal getActionLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setActionLocal(com.velocityme.interfaces.ActionLocal actionLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Issue-Task"
     *               role-name="Task-may-have-an-Issue"
     */
    public abstract com.velocityme.interfaces.IssueLocal getIssueLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setIssueLocal(com.velocityme.interfaces.IssueLocal IssueLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-CreatorContactable"
     *               role-name="Task-has-a-Creator"
     *               target-ejb="Contactable"
     *               target-role-name="CreatorContactable-has-a-Task"
     *               target-multiple="yes"
     * @jboss.relation fk-column="creatorContactableIdFk"
     *                 related-pk-field="contactableId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.ContactableValue"
     *                   aggregate-name="CreatorContactableValue"
     */
    public abstract com.velocityme.interfaces.ContactableLocal getCreatorContactableLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setCreatorContactableLocal(com.velocityme.interfaces.ContactableLocal creatorContactableLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-OwnerContactable"
     *               role-name="Task-has-an-Owner"
     *               target-ejb="Contactable"
     *               target-role-name="OwnerContactable-has-a-Task"
     *               target-multiple="yes"
     * @jboss.relation fk-column="ownerContactableIdFk"
     *                 related-pk-field="contactableId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.ContactableValue"
     *                   aggregate-name="OwnerContactableValue"
     */
    public abstract com.velocityme.interfaces.ContactableLocal getOwnerContactableLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setOwnerContactableLocal(com.velocityme.interfaces.ContactableLocal ownerContactableLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="TaskDependency-DependantTask"
     *               role-name="Task-has-many-Dependencies"
     */
    public abstract java.util.Collection getDependencyLinksLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setDependencyLinksLocal(java.util.Collection dependencyLinks);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="TaskDependency-DependencyTask"
     *               role-name="Task-has-many-Dependants"
     */
    public abstract java.util.Collection getDependantLinksLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setDependantLinksLocal(java.util.Collection dependantLinks);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-Responsible-Contactable"
     *               role-name="Task-may-have-many-ResponsibleContactables"
     * @jboss.relation fk-column="taskId"
     *                 related-pk-field="contactableId"
     * @jboss.relation-table table-name="responsiblecontactables"
     *                       create-table="true"
     *                       remove-table="false"
     */
    public abstract java.util.Collection getResponsibleContactablesLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setResponsibleContactablesLocal(java.util.Collection contactables);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-Interested-Contactable"
     *               role-name="Task-may-have-many-InterestedContactables"
     * @jboss.relation fk-column="taskId"
     *                 related-pk-field="contactableId"
     * @jboss.relation-table table-name="interestedcontactables"
     *                       create-table="true"
     *                       remove-table="false"
     */
    public abstract java.util.Collection getInterestedContactablesLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setInterestedContactablesLocal(java.util.Collection contactables);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-TaskStateMachine"
     *               role-name="Task-has-a-TaskStateMachine"
     *               target-ejb="TaskStateMachine"
     *               target-role-name="TaskStateMachine-has-many-Tasks"
     *               target-multiple="yes"
     * @jboss.relation fk-column="taskStateMachineIdFk"
     *                 related-pk-field="taskStateMachineId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.TaskStateMachineValue"
     *                   aggregate-name="TaskStateMachineValue"
     */
    public abstract com.velocityme.interfaces.TaskStateMachineLocal getTaskStateMachineLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTaskStateMachineLocal(com.velocityme.interfaces.TaskStateMachineLocal taskStateMachineLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-State"
     *               role-name="Task-has-a-State"
     *               target-ejb="State"
     *               target-role-name="State-has-many-Tasks"
     *               target-multiple="yes"
     * @jboss.relation fk-column="stateIdFk"
     *                 related-pk-field="stateId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.StateValue"
     *                   aggregate-name="StateValue"
     */
    public abstract com.velocityme.interfaces.StateLocal getStateLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStateLocal(com.velocityme.interfaces.StateLocal stateLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-Status"
     *               role-name="Task-has-a-Status"
     *               target-ejb="Status"
     *               target-role-name="Status-has-a-Task"
     *               target-multiple="yes"
     * @jboss.relation fk-column="statusIdFk"
     *                 related-pk-field="statusId"
     * @ejb.value-object match="*" 
     *                   aggregate="com.velocityme.valueobjects.StatusValue"
     *                   aggregate-name="StatusValue"
     */
    public abstract com.velocityme.interfaces.StatusLocal getStatusLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setStatusLocal(com.velocityme.interfaces.StatusLocal statusLocal);
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.relation name="Task-Time"
     *               role-name="Task-may-have-many-Times"
     */
    public abstract java.util.Collection getTimesLocal();
    /** @ejb.interface-method view-type="local" */
    public abstract void setTimesLocal(java.util.Collection times);
    
    //=======================================================================
    //
    //                   SELECT METHODS
    //
    //=======================================================================
    
    /**
     * @ejb.interface-method view-type="local"
     * @ejb.select query="SELECT DISTINCT OBJECT(t) FROM Search s, IN (s.searchLevelsLocal) l, IN (l.nodesLocal) k, Task t, IN (t.responsibleContactablesLocal) p WHERE s = ?1 AND t.nodeLocal = k AND p = ?2"
     */
    public abstract java.util.Collection ejbSelectMyTasks(com.velocityme.interfaces.SearchLocal p_search, com.velocityme.interfaces.ContactableLocal p_contactable) throws FinderException;
    
    //=======================================================================
    //
    //                   MANAGEMENT METHODS
    //
    //=======================================================================
    
    /**
     * @ejb.interface-method view-type="local"
     */
    public java.util.Collection getResponsibleContactablesValue() {
        Collection contactablesValue = new ArrayList();
        Collection contactablesLocal = getResponsibleContactablesLocal();
        Iterator i = contactablesLocal.iterator();
        while(i.hasNext()) {
            ContactableLocal contactableLocal = (ContactableLocal)i.next();
            contactablesValue.add(contactableLocal.getContactableValue());
        }
        return contactablesValue;
    }
    
    /**
     * @ejb.interface-method view-type="local"
     */
    public void setResponsibleContactablesValue(java.util.Collection p_contactablesValue) {
        Collection contactablesLocal = new ArrayList();
        Iterator i = p_contactablesValue.iterator();
        try {
            ContactableLocalHome contactableLocalHome = ContactableUtil.getLocalHome();
            while(i.hasNext()) {
                ContactableValue contactableValue = (ContactableValue)i.next();
                ContactableLocal contactableLocal = contactableLocalHome.findByPrimaryKey(contactableValue.getPrimaryKey());
                contactablesLocal.add(contactableLocal);
            }
            setResponsibleContactablesLocal(contactablesLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * @ejb.interface-method view-type="local"
     */
    public java.util.Collection getInterestedContactablesValue() {
        Collection contactablesValue = new ArrayList();
        Collection contactablesLocal = getInterestedContactablesLocal();
        Iterator i = contactablesLocal.iterator();
        while(i.hasNext()) {
            ContactableLocal contactableLocal = (ContactableLocal)i.next();
            contactablesValue.add(contactableLocal.getContactableValue());
        }
        return contactablesValue;
    }
    
    /**
     * @ejb.interface-method view-type="local"
     */
    public void setInterestedContactablesValue(java.util.Collection p_contactablesValue) {
        Collection contactablesLocal = new ArrayList();
        Iterator i = p_contactablesValue.iterator();
        try {
            ContactableLocalHome contactableLocalHome = ContactableUtil.getLocalHome();
            while(i.hasNext()) {
                ContactableValue contactableValue = (ContactableValue)i.next();
                ContactableLocal contactableLocal = contactableLocalHome.findByPrimaryKey(contactableValue.getPrimaryKey());
                contactablesLocal.add(contactableLocal);
            }
            setInterestedContactablesLocal(contactablesLocal);
        }
        catch(NamingException e) {
            throw new EJBException(e);
        }
        catch(FinderException e) {
            throw new EJBException(e);
        }
    }
    
    /**
     * @ejb.interface-method view-type="local"
     */
    public java.lang.String getProjectPathName() {
        ArrayList nodes = new ArrayList();
        NodeLocal parentNodeLocal = getNodeLocal().getParentNodeLocal();
        while(parentNodeLocal != null) {
            nodes.add(0, parentNodeLocal.getName());
            if (parentNodeLocal.getFinalType().equals("Project"))
                break;
            if (parentNodeLocal.getFinalType().equals("SystemNode"))
                break;
            parentNodeLocal = parentNodeLocal.getParentNodeLocal();
        }
        String pathName = new String();
        Iterator i = nodes.iterator();
        while(i.hasNext()) {
            pathName += (String)i.next() + "/";
        }
        return pathName;
    }
    
    /**
     * @ejb.interface-method view-type="local"
     */
    public int getRemainingDuration_min(Date p_date) {
        int remaining_min = getExpectedDuration_min();
        try {
            Collection timesLocal = TimeUtil.getLocalHome().findTaskTimeBeforeDate(getLocal(), p_date);
            Iterator i = timesLocal.iterator();
            Date date = null;
            while (i.hasNext()) {
                TimeLocal timeLocal = (TimeLocal)i.next();
                if (date == null || date.before(timeLocal.getStopTime())) {
                    date = timeLocal.getStopTime();
                    remaining_min = timeLocal.getRemainingDuration_min();
                }
            }
        } catch(NamingException e) {
            throw new EJBException(e);
        } catch(FinderException e) {
            throw new EJBException(e);
        }
        return remaining_min;
    }
    
}
